2025-08-16 11:20
Tags:
[SQL 핸드북] 데이터 무결성의 수호자, 도메인(Domain) 완벽 정복
많은 개발자와 데이터베이스 관리자들이 ‘도메인(Domain)‘이라고 하면 인터넷 주소를 먼저 떠올립니다. 하지만 관계형 데이터베이스(SQL)의 세계에서 도메인은 전혀 다른 의미를 가집니다. 그것은 바로 데이터의 무결성(Integrity)과 일관성을 지키기 위한 강력한 규칙의 집합이자, 잘 만들어진 ‘틀’입니다.
이 핸드북은 데이터베이스 설계의 품질을 한 단계 끌어올릴 수 있는 SQL 도메인의 모든 것을 다룹니다. 도메인이 왜 탄생했는지부터 실제 사용법과 장점까지, 이 글을 통해 당신의 데이터베이스는 더욱 견고하고 명확해질 것입니다.
1장: SQL 도메인은 왜 만들어졌을까? (탄생 배경)
데이터베이스를 설계하다 보면 반복적으로 나타나는 데이터 유형과 규칙들이 있습니다. 예를 들어, ‘이메일 주소’, ‘전화번호’, ‘우편번호’, ‘성별’과 같은 컬럼들입니다.
-
이메일 주소: 항상
'@'
기호를 포함해야 하고,VARCHAR(255)
정도의 길이를 가집니다. -
전화번호:
010-XXXX-XXXX
형식이어야 하고, 숫자와 하이픈(-)으로만 구성됩니다. -
성별: ‘남’, ‘여’ 또는 ‘M’, ‘F’ 와 같은 특정 값만 허용해야 합니다.
만약 이러한 컬럼들이 데이터베이스 내의 여러 테이블에 흩어져 있다면 어떻게 될까요? users
테이블의 email
컬럼, orders
테이블의 shipping_email
컬럼, invoices
테이블의 billing_email
컬럼 모두에 동일한 데이터 타입과 CHECK
제약 조건을 일일이 설정해야 합니다.
이러한 방식은 다음과 같은 문제점을 낳습니다.
-
반복적인 작업: 똑같은 코드를 여러 번 작성해야 하므로 비효율적입니다.
-
오류 발생 가능성: 테이블마다 규칙을 다르게 적용하는 실수가 발생할 수 있습니다. 예를 들어, 한 테이블에서는 이메일 길이를
VARCHAR(100)
으로, 다른 곳에서는VARCHAR(255)
로 설정할 수 있습니다. -
유지보수의 어려움: 만약 이메일 주소 규칙이 변경된다면? 이 규칙이 적용된 모든 테이블의 모든 컬럼을 찾아서 하나씩 수정해야 하는 끔찍한 상황이 발생합니다.
SQL 도메인은 바로 이 문제를 해결하기 위해 탄생했습니다. 특정 데이터 타입과 그에 따르는 제약 조건(Constraints), 기본값(Default)을 하나의 ‘사용자 정의 타입’ 으로 묶어서 재사용할 수 있게 만든 것입니다.
쉽게 비유하자면,
도메인 = 특정 모양과 규칙을 가진 ‘쿠키 틀’ 🍪
컬럼 = 쿠키 틀로 찍어낸 ‘쿠키 반죽’
‘별 모양’이라는 쿠키 틀(도메인)을 한 번 만들어두면, 언제든지 일관된 모양의 별 모양 쿠키(컬럼)를 찍어낼 수 있습니다. 쿠키 틀의 모양을 바꾸면, 앞으로 찍어내는 모든 쿠키의 모양도 함께 바뀝니다.
2장: SQL 도메인의 구조 파헤치기
SQL 도메인은 CREATE DOMAIN
구문을 사용하여 정의합니다. 그 구조는 다음과 같은 핵심 요소들로 이루어져 있습니다.
CREATE DOMAIN 도메인_이름
AS 기본_데이터_타입
[ DEFAULT 기본값 ]
[ CONSTRAINT 제약조건_이름 CHECK (조건식) ];
-
도메인_이름 (Domain Name)
- 새롭게 만들 사용자 정의 데이터 타입의 이름입니다. (
EMAIL_ADDRESS
,KR_PHONE_NUMBER
등)
- 새롭게 만들 사용자 정의 데이터 타입의 이름입니다. (
-
기본_데이터_타입 (Base Data Type)
- 도메인이 기반으로 할 표준 데이터 타입입니다. (
VARCHAR(255)
,INT
,DECIMAL(10, 2)
등)
- 도메인이 기반으로 할 표준 데이터 타입입니다. (
-
DEFAULT 기본값 (Optional)
- 해당 도메인을 사용하는 컬럼에 데이터가 명시적으로 입력되지 않았을 때 자동으로 설정될 기본값입니다. (예:
DEFAULT 'unspecified'
)
- 해당 도메인을 사용하는 컬럼에 데이터가 명시적으로 입력되지 않았을 때 자동으로 설정될 기본값입니다. (예:
-
CHECK (조건식) (Optional)
-
도메인의 핵심 기능입니다. 이 도메인에 입력되는 모든 데이터가 반드시 만족해야 하는 규칙을 정의합니다.
-
조건식 안에서는
VALUE
라는 특별한 키워드를 사용하여 현재 입력되려는 값을 참조할 수 있습니다.
-
실제 예시: 이메일 주소 도메인 만들기
-- 이메일 주소 형식을 검증하는 도메인을 생성합니다.
CREATE DOMAIN EMAIL_ADDRESS
AS VARCHAR(255) -- 기반 데이터 타입은 VARCHAR(255)
CONSTRAINT email_format_check CHECK (
-- VALUE는 현재 입력되려는 값을 의미합니다.
-- 정규 표현식을 사용하여 '@' 기호가 포함되고 기본적인 이메일 형식을 따르는지 검사합니다.
VALUE ~ '^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$'
);
이제 EMAIL_ADDRESS
라는, 단순한 VARCHAR
가 아닌 ‘이메일 형식 규칙이 내장된 특별한 타입’ 이 탄생한 것입니다.
3장: SQL 도메인은 어떻게 사용하는가? (생성, 적용, 수정, 삭제)
도메인을 정의했다면, 이제 테이블을 만들 때 일반 데이터 타입처럼 자유롭게 사용할 수 있습니다.
1. 테이블 생성 시 도메인 적용하기
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email EMAIL_ADDRESS NOT NULL, -- 우리가 만든 EMAIL_ADDRESS 도메인을 사용!
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE subscribers (
subscriber_id SERIAL PRIMARY KEY,
contact_email EMAIL_ADDRESS, -- 여기서도 재사용!
subscribed_on DATE
);
이제 users
테이블의 email
컬럼과 subscribers
테이블의 contact_email
컬럼은 모두 EMAIL_ADDRESS
도메인에 정의된 규칙(VARCHAR(255), 이메일 형식 체크)을 자동으로 따르게 됩니다.
만약 잘못된 형식의 이메일을 입력하려고 하면, 데이터베이스는 도메인의 CHECK
제약 조건에 따라 오류를 발생시키며 데이터 입력을 막습니다.
-- 성공: 올바른 이메일 형식
INSERT INTO users (username, email) VALUES ('john_doe', 'john.doe@example.com');
-- 실패: 도메인의 CHECK 제약 조건 위반으로 오류 발생!
INSERT INTO users (username, email) VALUES ('jane_doe', 'jane_doe_example.com');
-- ERROR: value for domain EMAIL_ADDRESS violates check constraint "email_format_check"
2. 도메인 수정하기 (ALTER DOMAIN
)
비즈니스 규칙이 변경되면 도메인 자체를 수정할 수 있습니다. 예를 들어, 새로운 제약 조건을 추가하거나 기존 제약 조건을 삭제할 수 있습니다.
-- 도메인에 새로운 제약 조건 추가
ALTER DOMAIN EMAIL_ADDRESS
ADD CONSTRAINT no_spam_domain_check CHECK (VALUE NOT LIKE '%@spam.com');
-- 도메인의 제약 조건 삭제
ALTER DOMAIN EMAIL_ADDRESS
DROP CONSTRAINT email_format_check;
가장 큰 장점은, 도메인을 한 번 수정하면 이 도메인을 사용하고 있는 모든 테이블의 모든 컬럼에 변경 사항이 즉시 적용된다는 것입니다. 유지보수가 극도로 간편해집니다.
3. 도메인 삭제하기 (DROP DOMAIN
)
더 이상 사용하지 않는 도메인은 삭제할 수 있습니다.
-- RESTRICT (기본값): 해당 도메인을 사용하는 객체(테이블 컬럼 등)가 있으면 삭제를 막음
DROP DOMAIN EMAIL_ADDRESS RESTRICT;
-- ERROR: cannot drop type email_address because other objects depend on it
-- CASCADE: 해당 도메인을 사용하는 모든 컬럼의 데이터 타입을 기반 타입(VARCHAR(255))으로 변경하고,
-- 관련된 제약 조건들을 모두 삭제한 후 도메인을 삭제함. (주의해서 사용해야 함)
DROP DOMAIN EMAIL_ADDRESS CASCADE;
4. 심화 학습: 도메인 vs. 컬럼 제약조건
“그냥 테이블 컬럼에 직접 CHECK
제약조건을 걸면 되는 것 아닌가요?” 라고 생각할 수 있습니다. 둘의 가장 큰 차이점은 ‘재사용성’ 과 ‘중앙 관리’ 입니다.
구분 | SQL 도메인 | 컬럼 CHECK 제약조건 |
---|---|---|
목적 | 데이터 타입 자체에 규칙을 부여 | 특정 컬럼에만 규칙을 부여 |
범위 | 데이터베이스 전체에서 재사용 가능 | 해당 컬럼에만 한정됨 |
일관성 | 중앙에서 관리하므로 강력한 일관성 보장 | 테이블마다 다르게 정의될 수 있음 |
유지보수 | 도메인 하나만 수정하면 일괄 적용되어 편리 | 규칙을 사용하는 모든 컬럼을 개별 수정해야 함 |
의미 | ’이메일 주소 타입’이라는 의미론적 타입 정의 | ’이 컬럼은 이메일 형식이어야 한다’는 규칙 |
단순히 한 테이블의 한 컬럼에만 적용될 일회성 규칙이라면 컬럼 제약조건이 더 적합할 수 있습니다. 하지만 데이터베이스 전반에 걸쳐 일관된 규칙을 적용해야 하는 데이터라면 도메인을 사용하는 것이 압도적으로 유리합니다.
참고: 데이터베이스별 지원 여부 CREATE DOMAIN
은 SQL 표준 기능이지만, 모든 데이터베이스 관리 시스템(RDBMS)이 완벽하게 지원하는 것은 아닙니다.
-
완벽 지원: PostgreSQL, Oracle
-
제한적/미지원: MySQL, MariaDB, SQL Server 등은 유사한 기능을 다른 방식(예: User-Defined Data Types, Rules)으로 구현하거나 지원하지 않는 경우가 있으므로, 사용 중인 RDBMS의 문서를 확인해야 합니다.
마치며
SQL 도메인은 단순히 코드를 줄여주는 편의 기능이 아닙니다. 그것은 데이터베이스 설계의 철학에 관한 것입니다. 도메인을 통해 우리는 “이 컬럼은 255자리의 문자열이다”를 넘어, “이 컬럼은 ‘이메일 주소’라는 의미를 가지며, 그에 합당한 규칙을 따른다” 라고 선언하는 것입니다.
이러한 선언은 데이터의 무결성을 보장하고, 코드의 가독성을 높이며, 장기적인 유지보수 비용을 획기적으로 줄여줍니다. 당신의 다음 데이터베이스 프로젝트에서는 이 강력한 ‘규칙의 틀’을 사용하여 더욱 견고하고 우아한 설계를 완성해 보시길 바랍니다.